#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include "../include/ring_buffer.h"

// 实现一个二维数据的ring_buffer 
// 问题是读：每个人私有一个in:以LCD的为主
// 最终提供一个ring_buffer_init函数 、
// 模仿linux下的 输入一个RingBuf结构体的指针  给他初始化好就行
// 在这里提供read write函数
// 这里的read函数抽象一点 只有LCD可以更新in
// 假设size只能是2的N次方

//? 一个问题就是当carama更新太快的时候(3到4倍)

/*
* size:ringbuffer的大小
*length:每一行的大小
*/
int init_ring_buffer(RingBuffer_t* rb, unsigned int size,unsigned int length)
{
    rb->buffer = (char**)malloc(size * sizeof(char*));
    if (rb->buffer == NULL) {
        fprintf(stderr, "Error: Failed to allocate memory for buffer array.\n");
        return -1; // malloc 失败，返回 -1
    }
    for(int i = 0;i < size;i++) {
        rb->buffer[i] = (char *) malloc(length * sizeof(char));
        if (rb->buffer[i] == NULL) {
            fprintf(stderr, "Error: Failed to allocate memory for buffer[%d].\n", i);
            // 如果其中一个 malloc 失败，释放之前成功分配的内存
            for (int j = 0; j < i; j++) {
                free(rb->buffer[j]);
            }
            free(rb->buffer);
            return -1; // malloc 失败，返回 -1
        }
    }
    rb->in = 0;
    rb->size = size;
    rb->length = length;
    rb->out = 0;
    return 0;
}
/*
* 写入ring_buffer 
* 正常返回0 不正常-1
*/
int ring_buffer_put(RingBuffer_t* rb, char* put_chars)
{
    memcpy(rb->buffer[(rb->in)&(rb->size - 1)],put_chars,rb->length);
    rb->in ++;
    return 0;
}

//get_index是私有的 每个人有自己的都是从0开始
int ring_buffer_get(RingBuffer_t* rb,char* get_chars,unsigned int* get_index)
{
    // 此时表明满了
    if(*get_index == rb->in)
        return -1;
    memcpy(get_chars,rb->buffer[(*get_index)&(rb->size - 1)],rb->length);

    // 然后再自增1
    *get_index = *get_index + 1;
    // 这里后面可以多一个flag去判断是不是LCD导致的满了
    return 0;

}
// 释放函数
int release_ring_buffer(RingBuffer_t* rb) {
    if(rb == NULL)
        return -1;

    // 释放每个 buffer_row 指向的内存
    for (int i = 0; i < rb->size; ++i) {
        free(rb->buffer[i]);
    }
    // 释放 buffer_row 数组本身
    free(rb->buffer);
    // 重置结构体成员
    rb->buffer = NULL;
    rb->size = 0;
    rb->length = 0;  // 假设结构体中是 rb->length 而不是 rb->lenth
    return 0;
}

// 写线程 --假设只有1个写线程
static void* write_thread(void* arg) {
    RingBuffer_t* rb = (RingBuffer_t*)arg;
    char data[10];
    for (int i = 0; i < 20; i++) {
        snprintf(data, sizeof(data), "Data %d", i);
        ring_buffer_put(rb, data);
        printf("Write: %s\n,in: %d\r\n", data,rb->in);
    }
    return NULL;
}

// 读线程
static void* read_thread(void* arg) {
    RingBuffer_t* rb = (RingBuffer_t*)arg;
    char data[10];
    unsigned int index = 0;
    while (1) {
        if (ring_buffer_get(rb, data, &index) == 0) {
            printf("Read: %s\n,index:%d\r\n", data,index);
        } else {
            continue;
        }
    }
    return NULL;
}
/*
int main()
{
    RingBuffer_t rb;
    pthread_t writer, reader1, reader2, reader3;

    // 初始化 ring_buffer
    if (init_ring_buffer(&rb, 8, 10) != 0) {
        fprintf(stderr, "Failed to initialize ring buffer.\n");
        return -1;
    }

    // 创建写线程
    pthread_create(&writer, NULL, write_thread, (void*)&rb);
    // 创建读线程
    pthread_create(&reader1, NULL, read_thread, (void*)&rb);
    pthread_create(&reader2, NULL, read_thread, (void*)&rb);
    pthread_create(&reader3, NULL, read_thread, (void*)&rb);

    // 等待写线程完成
    pthread_join(writer, NULL);
    // 等待读线程完成
    pthread_join(reader1, NULL);
    pthread_join(reader2, NULL);
    pthread_join(reader3, NULL);

    // 释放 ring_buffer
    release_ring_buffer(&rb);

    return 0;


}*/